package liu.de.config;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Objects;

/**
 * @author liude
 */
@EnableCaching
@Configuration
@Aspect
public class CacheConfig {
    @Bean
    public CacheManager redisCacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setUsePrefix(true);
        cacheManager.setDefaultExpiration(240);
        return cacheManager;
    }

    /**
     * 不使用注解缓存一个方法
     *
     * @param joinPoint joinPoint
     * @return Object
     */
    @Around(value = "execution(* liu.de.service.UserService.getUser(..))")
    public Object cacheMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        String key = joinPoint.getSignature().toString();
        Object[] args = joinPoint.getArgs();

        Cache cache = cacheManager.getCache(key);

        if (Objects.nonNull(cache.get(args))) {
            return cache.get(args).get();
        }

        Object result = joinPoint.proceed();
        cache.put(args, result);
        return result;
    }

    private final CacheManager cacheManager;

    @Autowired
    public CacheConfig(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }
}
